/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package spud;

import au.com.bytecode.opencsv.CSVReader;
import au.com.bytecode.opencsv.bean.ColumnPositionMappingStrategy;
import au.com.bytecode.opencsv.bean.CsvToBean;
import java.io.*;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.NamingException;

import spud.data.CsvRow;
import spud.util.SymbolExchangeUtils;
import spud.util.SymbolExchangeUtils.SymbolExchange;

/**
 *
 * @author bsmith
 */
public class CSVSpreadsheet {

    private String symbol;
    private String exchange;
    private String type;
    private File csvFile;
    private List<CsvRow> rows;
    private static final char SEPARATOR_CHAR = ',';
    private static final char QUOTE_CHAR = '"';
    private static final char ESCAPE_CHAR = '\\';
    private static final int DATA_STARTS_AT_LINE = 3;

    public CSVSpreadsheet(String symbol, String exchange, File csvFile) throws NamingException {//throws NamingException {
        this();
        this.symbol = symbol;
        assert (csvFile != null);
        this.csvFile = csvFile;
        loadCSV();
    }

    public CSVSpreadsheet(String symbol, File csvFile) throws NamingException {//throws NamingException {
        this(symbol, getDefaultExchange(), csvFile);
        String exchange;
        SymbolExchangeUtils seu = new SymbolExchangeUtils();
        SymbolExchange symbolExchange = seu.getSymbolExchange(symbol);
    }

    public CSVSpreadsheet() {
        super();
    }

    private static String getDefaultExchange() {
        return SymbolExchangeUtils.getDefaultExchange();
    }

    private void loadCSV() throws NamingException {
        try {
            loadHeader();
            loadBody();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(CSVSpreadsheet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(CSVSpreadsheet.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void loadHeader() throws IOException, NamingException {
        CSVReader reader = null;
        reader = new CSVReader(new FileReader(csvFile), SEPARATOR_CHAR, QUOTE_CHAR, ESCAPE_CHAR);
        String[] idLine = reader.readNext();
        String[] header = reader.readNext();
        loadIdLine(idLine);
        verifyHeaderLine(header);
        reader.close();
    }

    protected void loadIdLine(String[] idLine) throws NamingException {
        String symbol = idLine[0];
        if (!symbol.equals(this.symbol)) {
            throw new NamingException("Supplied symbol '" + this.symbol + " is not equal the one in the spreadsheet: '" + symbol);
        }
        type = idLine[1];
    }

    protected void verifyHeaderLine(String[] header) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    /**
     * Sets rows List.  If there are no rows read it is initialised to an empty List rather than being a null.
     * @throws IOException 
     */
    private void loadBody() throws IOException {
        CSVReader reader = null;
        reader = new CSVReader(new FileReader(csvFile), SEPARATOR_CHAR, QUOTE_CHAR, ESCAPE_CHAR, DATA_STARTS_AT_LINE);
        ColumnPositionMappingStrategy<CsvRow> strat = new ColumnPositionMappingStrategy<CsvRow>();
        strat.setType(CsvRow.class);
        String[] columns = new String[]{"Date", "Price", "LastTrade", "LastTime", "Change", "Open", "DayHigh", "DayLow", "Volume", "Dividend"}; // the fields to bind do in your JavaBean
        strat.setColumnMapping(columns);

        String[] line;

        CsvToBean<CsvRow> csvBean = new CsvToBean<CsvRow>();
        rows = csvBean.parse(strat, reader);
        reader.close();
    }

    public String getSymbol() {
        return this.symbol;
    }

    public List<CsvRow> getCsvList() {
        return rows;
    }

    public String toString() {
        String toString = "Spreadsheet for Share: " + getSymbol() + "\n";
        for (CsvRow row : getCsvList()) {
        }
        return toString;
    }
}
